#include <iostream>
#include <string.h>

#include "memPool_t.h"
#include "defs.h"

#include "Test.h"

size_t memPool_t::defaultPageSize = MAXSIZE; // affects all newly created pages
									  // i.e. a pool can have different size pages

int main()
{
	memPool_t::setDefaultPageSize(100);
	memPool_t mp1(3); //create pool with 3 pages, each of size 100
	memPool_t mp2;	  //create pool with 1 page, each of size 100
	memPool_t mp6;
	memPool_t::setDefaultPageSize(3);
	memPool_t mp3(3); //create pool with 3 pages, each of size 3
	memPool_t mp4(0); //create pool with 1 page, each of size 3 ---> 0 will be changed in the CTOR to 1
	memPool_t mp5; //create pool with 1 page, each of size 3
	memPool_t::setDefaultPageSize(4);
	memPool_t mp7;

	if(!mp3.setPosition(0))
		std::cout<<"Error setting position to 0 in mp3"<<std::endl;

	if(!mp3.setPosition(100))
		std::cout<<"Error setting position to 100 in mp3"<<std::endl;

	int a = 17;
	if(!mp3.write(&a , sizeof(int)))
		std::cout<<"Error writing "<<a<<" into mp3!"<<std::endl;

	/* mp3's pages now:  (1=used byte, 0=free byte)  
	/* p1= | 1 | 1 | 1 |
	/* p2= | 1 | 0 | 0 |
	/* p3= | 0 | 0 | 0 |
	*/ 

	int a1 = 18;
	if(!mp3.write(&a1, sizeof(int), 1))
		std::cout<<"Error writing "<<a1<<" into mp3!"<<std::endl;

	/* mp3's pages now:    
	/* p1= | 1 | 1 | 1 |
	/* p2= | 1 | 1 | 0 |
	/* p3= | 0 | 0 | 0 |
	*/ 

	int a2 = 19;
	if(!mp3.write(&a2, sizeof(int), 3))
		std::cout<<"Error writing "<<a2<<" into mp3!"<<std::endl;

	/* mp3's pages now:    
	/* p1= | 1 | 1 | 1 |
	/* p2= | 1 | 1 | 1 |
	/* p3= | 1 | 0 | 0 |
	*/       

	if(!mp1.write(&a,sizeof(int)))
		std::cout<<"Error writing "<<a<<" into mp1!"<<std::endl;
	if(!mp1.write(&a1,sizeof(int)))
		std::cout<<"Error writing "<<a1<<" into mp1!"<<std::endl;

	if(!mp4.write(&a,sizeof(int)))
		std::cout<<"Error writing "<<a<<" into mp4!"<<std::endl;
	
	int b;
	if(!mp3.read(&b, sizeof(int), 3))
		std::cout<<"Error reading mp3 into b!"<<std::endl;
	std::cout<<"b="<<b<<std::endl<<std::endl; // b=19


	Test test(17, 5.324, true, 7000);

	if(!mp2.write(&test, sizeof(Test)))
		std::cout<<"Error writing test into mp2!"<<std::endl;
	if(!mp5.write(&test, sizeof(Test)))
		std::cout<<"Error writing test into mp5!"<<std::endl;

	Test t1, t2;
	if(!mp2.read(&t1, sizeof(Test), 0))
		std::cout<<"Error reading t1 into mp5!"<<std::endl;
	std::cout<<"t1: "<<t1<<std::endl;

	if(!mp5.read(&t2, sizeof(Test), 0))
		std::cout<<"Error reading t2 into mp5!"<<std::endl;
	std::cout<<"t2: "<<t2<<std::endl;

	if(!mp7.write(&a,sizeof(int)))
		std::cout<<"Error writing a into mp7"<<std::endl;
	if(!mp7.write(&a,sizeof(int)))
		std::cout<<"Error writing a into mp7 for the second time"<<std::endl;
	int read1,read2;
	if(!mp7.read(&read1,4,0))
		std::cout<<"cant read from mp7"<<std::endl;
	if(!mp7.read(&read2,4,4))
		std::cout<<"cant read from mp7 for the second time"<<std::endl;
	if(read1!=a || read2!=a)
		std::cout<<"mp7 test fail: ";
	else
		std::cout<<"mp7 test success: ";
	std::cout<<"a="<<a<<", read1="<<read1<<", read2="<<read2<<std::endl;


	/***************** Failures ******************/
	if(!mp6.write(&t2, sizeof(Test), 1))
		std::cout<<"This should fail because we are creating a hole in memory"<<std::endl;

	if(!mp4.read(&t2, 1000, 0))
		std::cout<<"This should fail because we are trying to read too much"<<std::endl;

	if(!mp1.read(&t1, 1, 90))
		std::cout<<"This should fail because we are trying to read were no data is avaliable"<<std::endl;


	/********* Stats ******************************/
	std::cout<<"is mp1 empty? "<<(mp1.isPoolEmpty()?"yes":"no")<<std::endl;
	std::cout<<"is mp2 empty? "<<(mp2.isPoolEmpty()?"yes":"no")<<std::endl;
	std::cout<<"is mp3 empty? "<<(mp3.isPoolEmpty()?"yes":"no")<<std::endl;
	std::cout<<"is mp4 empty? "<<(mp4.isPoolEmpty()?"yes":"no")<<std::endl;
	std::cout<<"is mp5 empty? "<<(mp5.isPoolEmpty()?"yes":"no")<<std::endl;
	std::cout<<"is mp6 empty? "<<(mp6.isPoolEmpty()?"yes":"no")<<std::endl; //should be "yes"
	std::cout<<"is mp7 empty? "<<(mp7.isPoolEmpty()?"yes":"no")<<std::endl<<std::endl;
	
	std::cout<<"mp1 info: ";
	mp1.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp2 info: ";
	mp2.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp3 info: ";
	mp3.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp4 info: ";
	mp4.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp5 info: ";
	mp5.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp6 info: ";
	mp6.printInfo();
	std::cout<<std::endl;

	std::cout<<"mp7 info: ";
	mp7.printInfo();
	std::cout<<std::endl<<std::endl;
	
	std::cout<<"done"<<std::endl;

	getchar();
	return 0;
}